<?php
/**
 * Created by PhpStorm.
 * User: lengbin
 * Date: 2018/5/15
 * Time: 下午6:27
 */

namespace common\core\filter;


use common\core\base\InvalidException;
use common\helpers\CodeHelper;
use yii\filters\auth\AuthMethod;
use yii\helpers\ArrayHelper;
use yii\web\IdentityInterface;
use yii\web\Request;
use yii\web\Response;
use yii\web\UnauthorizedHttpException;
use yii\web\User;

class SignAuth extends AuthMethod
{

    use InvalidException;

    public $type = 'header';
    public $signParam = '';
    public $timestampParam = '';

    /**
     *
     * @param \yii\web\Response $response
     *
     * @throws \yii\base\UserException
     */
    public function handleFailure($response)
    {
        $this->invalidRequestException('', CodeHelper::SYS_SIGN_ERROR);
    }

    /**
     * Authenticates the current user.
     *
     * @param User     $user
     * @param Request  $request
     * @param Response $response
     *
     * @return bool|IdentityInterface
     */
    public function authenticate($user, $request, $response)
    {
        $secretKey = ArrayHelper::getValue(\Yii::$app->params, 'secretKey', false);
        if ($secretKey === false) {
            return true;
        }
        $gets = $request->get();
        $posts = $request->post();
        $params = array_merge($gets, $posts);

        if ($this->type === 'header') {
            $sign = $request->headers->get($this->signParam ? $this->signParam : 'X-Sign');
            $timestamp = $request->headers->get($this->timestampParam ? $this->timestampParam : 'X-Timestamp');
        } else {
            $sign = ArrayHelper::remove($params, $this->signParam ? $this->signParam : 'sign');
            $timestamp = ArrayHelper::remove($params, $this->timestampParam ? $this->timestampParam : 'timestamp');
        }

        //过滤掉为空的参数
        $filterParams = [];
        foreach ($params as $k => $v) {
            if (is_array($v)) {
                $v = json_encode($v);
            }
            if (trim($v) != '') {
                $filterParams[$k] = $v;
            }
        }

        ksort($filterParams);

        $str = http_build_query($filterParams);
        $str = urldecode($str);

        if ($str != '') {
            $str .= '&timestamp=' . $timestamp;
        } else {
            $str = 'timestamp=' . $timestamp;
        }

        $str .= '&key=' . $secretKey;

        $targetSign = md5($str);
        return $targetSign === $sign ? true : null;
    }
}